<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
      body {
        padding: 20px;
      }
      div, p, li {
        line-height: 40px;
      }
      span {
        color: red;
      }
    </style>
</head>
<body>
  <div>Map与Set一样，都是构造函数，实例属于Object类型</div>
  <ul>
    <li>
      Javascript的对象本质上是键值对的集合（Hash结构），但是只能用字符串作为键，<span>（如果不是，则[]内自动转化为字符串）</span>为了解决这个问题，ES6提供了Map数据结构。它类似于对象，也是键值对的集合，但是“键”的范围<span>不限于字符串，各种类型的值</span>都可以当作键。也就是说，Object结构提供了“字符串--值”的对应，Map结构提供了“值--值”的对应，是一种更完善的Hash结构实现。如果需要“键值对”的数据结构，Map比Object更合适
    </li>
    <li>
      作为构造函数，Map也可以接受一个数组作为参数，该数组的成员是一个个表示键值对的数组
    </li>
    <li>
      事实上,不仅仅是数组,任何具有Iterator接口且每个成员都是一个双元素数组的数据结构都可以作为Map构造函数的参数.也就是说,Set和Map都可以用来生成新的Map
    </li>
    <li>
      如果对同一个键多次set,后面的值将会覆盖前面的值
    </li>
    <li>
      Map的键是一个简单类型的值(数字,字符串,布尔值),则只要两个值严格相等,Map就将其视为一个键,包括0和-0,另外,虽然NaN不严格等于自身,但Map将其视为同一个键.
    </li>
    <li>
      Map的键实际上是和内存地址绑定的,只要内存地址不一样,就视为两个键.这就解决了同名属性碰撞的问题
    </li>
    <li>
      <h3>实例属性和操作方法</h3>
      <ul>
        <li>size: size属性返回Map结构的成员总数</li>
        <li>set(key, value): set方法设置key所对应的键值,然后返回整个Map结构.如果key已经有值,则键值会被更新,否则就新生成该键</li>
        <li>get: 读取key对应的值,如果找不到key,则返回undefined</li>
        <li>has(key):has方法返回一个布尔值,表示某个键是否在Map数据结构中.</li>
        <li>delete(key): delete方法删除某个键,返回true.如果删除失败,则返回false</li>
        <li>clear(): clear方法清除所有成员,没有返回值</li>
      </ul>
    </li>
    <li>
      <h3>遍历方法</h3>
      <ul>
        <li>keys(): 返回键名的遍历器</li>
        <li>values(): 返回键对应的值的遍历器</li>
        <li>entries(): 返回所有成员的遍历器</li>
        <li>forEach(): 遍历Map的所有成员</li>
        <li>
          注意:map的遍历顺序就是插入顺序,Map结构的默认遍历器接口,就是entries()方法.
        </li>
      </ul>
    </li>
  </ul>
</body>
</html>